/*
 * Copyright 2008 Zoundry LLC, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.zoundry.gaedt.core.util;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.zoundry.gaedt.core.ZGaeCoreActivator;


/**
 * Some static utility methods.
 */
public final class ZGaeUtil
{
    public static final String ID_CONSOLE_VIEW = "org.eclipse.ui.console.ConsoleView"; //$NON-NLS-1$

    /**
     * Private util class c'tor.
     */
    private ZGaeUtil()
    {
    }

    /**
     * Shows (and brings to the front) the view with the given ID.
     *
     * @param aViewId
     */
    public static IViewPart showView(final String aViewId)
    {
        ZGaeCoreActivator activator = ZGaeCoreActivator.getDefault();
        IWorkbench workbench = activator.getWorkbench();
        IWorkbenchWindow activeWorkbenchWindow = workbench.getActiveWorkbenchWindow();
        IWorkbenchPage page = activeWorkbenchWindow.getActivePage();
        try
        {
            if (page != null)
            {
                IViewPart view = page.showView(aViewId, null, IWorkbenchPage.VIEW_VISIBLE);
                if (view != null)
                {
                    return view;
                }
            }
        }
        catch (PartInitException ex)
        {
            logError(ex);
        }
        return null;
    }

    /**
     * Log an exception to the error log.
     *
     * @param aError
     */
    public static void logError(Throwable aError)
    {
        ZGaeCoreActivator activator = ZGaeCoreActivator.getDefault();
        if (activator == null)
        {
            aError.printStackTrace();
        }
        else
        {
            String id = ZGaeCoreActivator.getDefault().getBundle().getSymbolicName();
            IStatus status = new Status(IStatus.ERROR, id, IStatus.ERROR, aError.getLocalizedMessage(), aError);
            ZGaeCoreActivator.getDefault().getLog().log(status);
        }
    }

    /**
     * Log an exception to the error log and display it in a dialog to the
     * user.
     *
     * @param aError
     */
    public static void logAndDisplayError(final Throwable aError)
    {
        // If already on the UI thread, open error dialog, else we need to asyncExec to a UI thread
        if (Display.getCurrent() != null)
        {
            // display the error to the user.
            logAndDisplayErrorInternal(aError);
        }
        else
        {
            Display.getDefault().asyncExec(new Runnable()
            {
                public void run()
                {
                    // display the error to the user.
                    logAndDisplayErrorInternal(aError);
                }
            });
        }
    }

    /**
     * Logs the given error to the Eclipse error log View and displays a standard
     * Eclipse error dialog.  The error dialog's details area will be populated with
     * the getMessage text associated with the Exception.
     *
     * @param aError the Exception that we are logging.
     */
    protected static void logAndDisplayErrorInternal(Throwable aError)
    {
        // Log error to the Eclipse error log view.
        logError(aError);

        String title = "Error Encountered";
        String summary = aError.getLocalizedMessage();

        // Prepare a Status error object for the error dialog.
        final StringBuffer reason = new StringBuffer();
        reason.append(aError.getLocalizedMessage());
        reason.append("See the error log (Eclipse View) for details.");

        String id = Platform.getBundle(PlatformUI.PLUGIN_ID).getSymbolicName();
        Status errStatus = new Status(IStatus.ERROR, id, IStatus.ERROR, reason.toString(), aError);
        ErrorDialog.openError(getShell(), title, summary, errStatus);
    }

    /**
     * Returns the current shell or default shell if not on a ui thread.
     */
    public static Shell getShell()
    {
       return Display.getCurrent() != null ? Display.getCurrent().getActiveShell() : Display.getDefault().getActiveShell();
    }

    /**
     * Returns the current active workbench window.
     */
    public static IWorkbenchWindow getActiveWorkbenchWindow()
    {
        IWorkbenchWindow window;
        // If already on the UI thread, open error dialog, else we need to syncExec from a UI thread
        if (Display.getCurrent() != null)
        {
            window = ZGaeCoreActivator.getDefault().getWorkbench().getActiveWorkbenchWindow();
        }
        else
        {
            AevWorkbenchWindowGetter get = new AevWorkbenchWindowGetter();
            Display.getDefault().syncExec(get);
            window = get.getActiveWorkbenchWindow();
        }
        return window;
    }

    /**
     * This class implements a simple get of the active workbench window while on the ui thread.
     */
    private static class AevWorkbenchWindowGetter implements Runnable
    {
        private IWorkbenchWindow mActiveWorkbenchWindow;

        /**
         * @see java.lang.Runnable#run()
         */
        public void run()
        {
            mActiveWorkbenchWindow = ZGaeCoreActivator.getDefault().getWorkbench().getActiveWorkbenchWindow();
        }

        /**
         * @return Returns the workbenchWindow.
         */
        public IWorkbenchWindow getActiveWorkbenchWindow()
        {
            return mActiveWorkbenchWindow;
        }
    }
}
